# Mobroute

[![builds.sr.ht status](https://builds.sr.ht/~mil/mobroute.svg)](https://builds.sr.ht/~mil/mobroute?)

Mobroute is a minimal FOSS public-transportation router
and suite of tools allowing you to route between locations
by using public transportation data (GTFS) data. GTFS
feeds are automatically fetched from the from the [Mobility
Database](https://github.com/MobilityData/mobility-database-catalogs) and
the application is designed to have as few 'knobs' to adjust before being
practically useful. The core of the routing algorithm is based on the
Connection Scan Algorithm. Mobroute also provides auxiliary support for 
functionality using the same GTFS data including: stop times / timetables
lookups for nearby stations, assistance finding all nearby stations.

Currently Mobroute is in active development and as such is
primarily aimed at early adopters and those who wish to help
with testing.  In it's current state Mobroute is an alpha stage,
routing works for select metros and features are being built
out based on the [roadmap doc](doc/roadmap.md). See the [mailing list
note](https://lists.sr.ht/~mil/mepo-devel/%3C9e35583d-c97c-4978-a06a-fd501cf548b4%40app.fastmail.com%3E)
for historical project details.

**The Mobroute project is composed of 3 separate codebases / smaller projects:**
  - [Mobsql](http://git.sr.ht/~mil/mobsql): is a GTFS-to-SQL ETL tool which
    pulls GTFS sources from the MobilityDB into a SQLite database. It exposes
    both a CLI & a Go library (consumed by Mobroute).
  - [Mobroute](http://git.sr.ht/~mil/mobroute): is the core routing tool. This
    project handles interfacing Mobsql via its public Go API and then once the
    DB is loaded, opens the DB and performs routing calculations (currently via
    the Connection Scan Algorithm). It exposes both a CLI & a Go library (
    consumed by Transito).
  - [Transito](http://git.sr.ht/~mil/transito): is a simple Android & Linux GUI 
    app to use Mobroute. It allows querying from/to via Nominatim and
    performing routing calculations on-the-go via Mobroute's underlying
    routing mechanism (note this implicitly integrates Mobsql as well).

## **Featureset**

Below is an overview of the main features of Mobroute:

- Well-executed **singlemodal public transportation routing** via GTFS data
  - Project focuses on implementing only GTFS routing providing for algorithmic & codebase simplicity
  - Other routers bill themselves as "multimodal"; Mobroute is proudly singlemodal (doesn't integrate automobile/OSM/PBF data)
  - Overall.. *does one thing well*: public transportation routing
- Integration of **automatic GTFS dataimport** & ETL out-of-the-box via [the Mobility Database](https://database.mobilitydata.org/)
  - Frees user from having to source & manually download/import GTFS zip archives
  - System automatically downloads the data needed for a routing requests *upon use*
  - Supports using multiple GTFS sources independently and in combination for single routing requests
  - See [Mobsql](http://git.sr.ht/~mil/mobsql) for details on ETL pipeline, uses SQLite under the hood
- Efficient algorithmic routing via the **Connection Scan Algorithm** (CSA)
  - Being a singlemodal router lends Mobroute's design to implementation simplicity
  - The well academically studied CSA algorithm is utilized: see [paper details here](https://i11www.iti.kit.edu/extra/publications/dpsw-isftr-13.pdf)
  - CSA is non-graphbased, simple, and Mobroute's CSA implementation is well tested
- Targeted to **on-device and offline usage**
  - Designed to be used on-device and offline once data is fetched
  - Run your routing request right on your mobile device for the privacy conscious
- Fully thought-out **small, simple, & modular design supporting library, CLI, & mobile usage**
  - Built in Go, the design of the project is small and modular
  - 3 primary components:
    - Mobsql (GTFS-to-SQLite ETL pipeline)
    - Mobroute (Core routing algorithm via CSA)
    - Transito (Graphical mobile application for Android & Linux)
  - Mobsql and Mobroute can be used as both a CLI OR as a Go API as a library in your application
  - Transito, Mobroute's mobile application is written in Go (via [Gio](https://gioui.org/)) and uses Mobroute's API 

## **How to Use Mobroute**

Currently there are three primary ways to use Mobroute: (1) via a mobile
(and desktop) graphical application for Android & Linux named Transito,
(2) via Mepo, the graphical Linux OSM app, using from/to prompts (via
a GTK GUI), and (3) via the commandline. Eventually a Go API will also
be stabilized and accessible for usage in custom applications.

See documentation for each usage pattern below:
- [Transito](https://git.sr.ht/~mil/transito): Use Mobroute via its graphical Android & Linux application
- [Mepo Integration](doc/mepo_integration.md): Use Mobroute to calculate a route and plot the result in the Linux OSM app, Mepo
- [CLI](doc/cli.md): Use Mobroute's commandline interface directly


## **Working Routing Requests**

The routing request for the below select metros have been smoketested
and are known to generate functional routes. Any valid GTFS source from
the Mobility Database should work with Mobroute - however these examples
have been explicitly tested against. Add your metro example here. The
purpose of this section is for end-users to get a sense of capabilities of
Mobroute's routing API in terms of inputs and outputs. Note that dataload
from the Mobility Database is a fully automated process so simply plugging
a YML request buffer similar to the buffers below into Mobroute is all
you need to start generate working routes in a single command.

The request YML examples shown below can be plugged into [Mobroute on
the commandline](doc/cli.md) using `mobroute route -p 'YML'` or the same
parameters may be used in Transito.

| Mdbid | Country | Municipality | Name | From | To | Request YML | Output |
| ----- | ------- | ------------ | ---- | ---- | -- | ----------- | ------ |
| 516 | US | New York City | MTA New York City Transit (MTA): NYC Subway | [40.70940, -74.00537](https://www.openstreetmap.org/?mlat=40.70940&mlon=-74.00537) | [40.72879, -73.95215](https://www.openstreetmap.org/?mlat=40.72879&mlon=-73.95215) | `{filter: {mdbid: [516] }, from: {lat: 40.70940, lon: -74.00537}, to: {lat: 40.72879, lon: -73.95215}, time: 2023-12-27T15:04:05Z}` | [Output](doc/route_output_samples/516.json) |
| 1270 | PL | Kraków | Zarząd Transportu Publicznego w Krakowie (ZTP Kraków): Tram | [50.012338, 19.88192](https://www.openstreetmap.org/?mlat=50.012338&mlon=19.88192) | [50.08785, 20.02387](https://www.openstreetmap.org/?mlat=50.08785&mlon=20.02387) | `{filter: {mdbid: [1270]}, from: {lat: 50.012338, lon: 19.88192}, to: {lat: 50.08785, lon: 20.02387}, time: 2023-12-27T15:04:05Z}` | [Output](doc/route_output_samples/1270.json) |
| 1088 | BE | Bruxelles | Société des Transports Intercommunaux de Bruxelles/Maatschappij voor het Intercommunaal Vervoer te Brussel (STIB/MIVB) | [50.85728, 4.351426](https://www.openstreetmap.org/?mlat=50.85728&mlon=4.351426) | [50.83214, 4.350534](https://www.openstreetmap.org/?mlat=50.83214&mlon=4.350534) | `{filter: {mdbid: [1088]}, from: {lat: 50.85728, lon: 4.351426}, to: {lat: 50.83214, lon: 4.350534}, time: 2023-12-27T15:04:05Z}` | [Output](doc/route_output_samples/1088.json) |
| 1898 | FR | Bourges | Agglobus | [47.07199, 2.40154](https://www.openstreetmap.org/?mlat=47.07199&mlon=2.40154) | [47.10811, 2.41974](https://www.openstreetmap.org/?mlat=47.10811&mlon=2.41974) | `{filter: {mdbid: [1898]}, from: {lat: 47.07199, lon: 2.40154}, to: {lat: 47.10811, lon: 2.41974}, time: 2023-12-27T15:04:05Z}` | [Output](doc/route_output_samples/1898.json) |
| 1032 | PT | Unset | Carris | [38.7376, -9.1725](https://www.openstreetmap.org/?mlat=38.7376&mlon=-9.1725) | [38.72329, -9.14646](https://www.openstreetmap.org/?mlat=38.72329&mlon=-9.14646) | `{filter: {mdbid: [1032]}, from: {lat: 38.7376, lon: -9.1725}, to: {lat: 38.72329, lon: -9.14646}, time: 2023-12-27T15:04:05Z, max_transfer_seconds: 600}` | [Output](doc/route_output_samples/1032.json) |

Multiples sources can be used in a single routing request as well. The
most efficient path will be generated with transfers taken between the
seperate providers when this is the most efficient route, examples below:

| Mdbid | Country | Municipality | Name | From | To | Request YML | Output |
| ----- | ------- | ------------ | ---- | ---- | -- | ----------- | ------ |
| 509 + 516 | US + US | Unset + New York City | New Jersey Transit (NJ Transit): Rail + MTA New York City Transit (MTA): NYC Subway | [40.64809, -73.93799](https://www.openstreetmap.org/?mlat=40.64809&mlon=-73.93799) | [40.82732, -74.12064](https://www.openstreetmap.org/?mlat=40.82732&mlon=-74.12064) | `{filter: {mdbid: [509, 516]}, from: {lat: 40.64809, lon: -73.93799}, to: {lat: 40.82732, lon: -74.12064}}` | [Output](doc/route_output_samples/509_516.json) |

## **Known Limitations**
As the Mobroute project is a work in progress overall there are a
number of known defects and limitations to note. See the [roadmap
doc](doc/roadmap.md) for details on planned features and overall project
state. This list is in supplement to the roadmap in order to provide a
simple readable format of known limitations to set expectations if you
are trying Mobroute locally or using Transito on your mobile device.

- The SQLite database is stored uncompressed and the schema used is currently
  relatively unoptimized. Thus the DB size is several factors larger then it
  needs to be and devices with small storage capacities may struggle or fail
  in load.
- Large GTFS archive sources may fail or take a long time to load. Extracted 
  stop_times.txt up to ~200MB or so have been successfully tested locally
  and larger sources should work; but this is dependent on local resources.
- GTFS feeds not providing transfers.txt & multiple-GTFS feed requests, e.g.
  using generated transfers is relatively unoptimized and can be slow to load
  dependent on the threshold set for max_transfer_seconds; if you want to
  use multiple feeds or generated transfers quickly, set max_transfer_seconds
  to a lower value.
- GTFS sources with multiple agencies provided in the GTFS agency.txt table
  may not produce accurate routes as this is unaccounted for in loading.
- Routing requests currently do not work beyond the boundaries of a single
  day (thus requests just before midnight may produce invalid routes).
- Indexes are maintained during load and compute stages (thus producing
  much slower then possible import speeds); the more data you import into the
  system, likely the slower subsequent imports will be.
- It is difficult given the current design of Mobsql's filter specification
  to load certain sources together outside of manually addressing sources
  by mdbid (better and/or logic design is needed here).
- The design of the routing runtime, first loading the data needed into memory
  and then executing the routing request needs to be rethought. CSA (the 
  routing algorithm) is quite fast; while the most costly piece of routing 
  is loading to memory the data needed (which is cachable/memoizable) but
  is currently not treated as cached and always runs for all requests on 
  the CLI & in Transito.
- As of 0.2, the stops and stoptimes commands are nonfunctional as formatting
  and the codebase as a whole was reworked; these commands will be added back
  in the future


## **Demo Videos**

Note these demo videos are considered historical at this point and new videos
need to be produced at some point. These videos show a very early conception
of Mobroute's functionality.

- [Mobroute CLI Demo Video](https://media.lrdu.org/mobroute_demos/mobroute_demo.ogv)
- [Mobroute Mepo Integration Demo Video](https://media.lrdu.org/mobroute_demos/mobroute_mepo_demo.ogv)

## **Contribute**

Important Links:
- Mailing List: https://lists.sr.ht/~mil/mobroute-devel
- Tickets: https://todo.sr.ht/~mil/mobroute-tickets
- Development Guide: https://git.sr.ht/~mil/mobroute/tree/master/item/doc/devguide.md
- IRC: #mepo on irc.oftc.net

The primary targets for development over the next number of months can
be seen on the [roadmap doc](doc/roadmap.md).

If you wish to contribute features, help with testing, want to tackle
something on the roadmap, or similar in order to help get Mobroute
to a more usable state this help is more then welcomed. Please get in
touch either on the mailing list, ticket tracker, directly via email,
or reach out on IRC. I can guide you if you have technical skills and
have a a particular feature you wish to contribute and if you are a
non-technical user struggling with using Mobroute I may be able to help
unblock you. Note for all users, this project is in active development -
bug reports and patches are welcome.

As for funding, currently development is being funded by
[NLnet](https://nlnet.nl/project/Mobroute/) which has kindly awarded
a grant to support Mobroute's development efforts as part of the
NGI0 Entrust Fund under grant agreement No 101069594. If you wish to
contribute financially please contact me at my [publicly available
email](http://milesalan.com).
